<template>
  <div class="route" v-loading="loading">
    <div v-if="routeList.length !== 0">
      <div class="item" v-for="item in routeList" :key="item.id">
        <div class="left">
          <div class="title" @click="toDetail(item)">{{ item.name }}</div>
        </div>
        <div class="right">
          <div class="show">
            <div class="publish-time">
              发布于：{{ formatDate(item.createTime) }}
            </div>
            <div class="info">
              <span>
                <i class="el-icon-chat-dot-square"> </i>
                {{ item.remarkCount }}
              </span>
              <span><i class="el-icon-view"></i>{{ item.views }}</span>
              <span>
                <svg
                  width="13"
                  height="13"
                  viewBox="0 0 48 48"
                  fill="rgb(250, 40, 40)"
                  xmlns="http://www.w3.org/2000/svg"
                >
                  <path
                    d="M15 8C8.92487 8 4 12.9249 4 19C4 30 17 40 24 42.3262C31 40 44 30 44 19C44 12.9249 39.0751 8 33 8C29.2797 8 25.9907 9.8469 24 12.6738C22.0093 9.8469 18.7203 8 15 8Z"
                    fill="none"
                    stroke="#999"
                    stroke-width="4"
                    stroke-linecap="round"
                    stroke-linejoin="round"
                  />
                </svg>
                {{ item.praise }}
              </span>
            </div>
          </div>
          <div class="option">
            <el-dropdown trigger="click">
              <span style="font-size: 18px">...</span>
              <el-dropdown-menu slot="dropdown">
                <el-dropdown-item icon="el-icon-edit" style="color: #409eff">
                  <span @click="edit(item)">修改</span>
                </el-dropdown-item>
                <el-dropdown-item
                  icon="el-icon-delete"
                  style="color: #f56c6c"
                  divided
                >
                  <span @click="del(item)">删除</span>
                </el-dropdown-item>
              </el-dropdown-menu>
            </el-dropdown>
          </div>
        </div>
      </div>
      <!-- 分页 -->
      <el-pagination
        v-show="routeList.length > 0"
        layout="prev, pager, next"
        :total="total"
        :current-page="currentPage"
        :page-size="pageSize"
        @current-change="handleCurrentChange"
        :page-count="7"
        style="text-align: right; margin-top: 24px"
      >
      </el-pagination>
    </div>
    <el-empty v-else description="暂无数据"></el-empty>

    <!-- 修改 -->
    <el-dialog
      title="修改线路"
      :visible.sync="updateDialogVisible"
      width="56%"
      @close="handleCloseUpdate"
      :close-on-click-modal="false"
    >
      <el-form
        :model="updateData"
        label-width="90px"
        :rules="rules"
        ref="updateForm"
      >
        <el-form-item label="线路名称" style="width: 84%" prop="name">
          <el-input
            v-model="updateData.name"
            placeholder="请输入线路名称"
            :clearable="true"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item label="温度(℃)" style="width: 26%" prop="temperature">
          <el-input
            v-model="updateData.temperature"
            placeholder="请输入温度"
            :clearable="true"
            autocomplete="off"
          >
          </el-input>
          <span class="tip">(*999表示为暂无温度)</span>
        </el-form-item>
        <el-form-item label="地理位置" style="width: 24%" prop="geographyId">
          <el-select
            v-model="updateData.geographyId"
            :clearable="true"
            style="width: 100px"
          >
            <el-option
              v-for="item in geographyList"
              :key="item.id"
              :label="item.type"
              :value="item.id"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="简介" style="width: 84%" prop="introduce">
          <el-input
            v-model="updateData.introduce"
            type="textarea"
            :rows="2"
            placeholder="请输入简介"
            :clearable="true"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item label="图片" style="width: 84%" prop="cover">
          <div class="upload-cover">
            <div class="cover">
              <img :src="updateData.cover || defaultCover" alt="" />
              <el-upload
                action="zhanweifu"
                :auto-upload="false"
                :show-file-list="false"
                :on-change="changeFile"
              >
                <span v-loading="uploadLoading"></span>
              </el-upload>
            </div>
          </div>
        </el-form-item>
        <el-form-item label="详情" style="width: 90%" prop="detail">
          <div class="editor-container">
            <Toolbar
              style="border-bottom: 1px solid #ccc"
              :editor="editor"
              :defaultConfig="toolbarConfig"
              :mode="mode"
            />
            <Editor
              style="height: 500px; overflow-y: hidden"
              v-model="html"
              :defaultConfig="editorConfig"
              :mode="mode"
              @onCreated="onCreated"
            />
          </div>
        </el-form-item>
      </el-form>
      <span slot="footer">
        <el-button @click="updateDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="update" :loading="updateLoading"
          >确 定</el-button
        >
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import defaultCover from "@/assets/defaultCover.png";
import { uploadFile } from "@/api/common";
import {
  addRouteViews,
  deleteById,
  getGeographyList,
  getRouteList,
  updateRoute,
} from "@/api/user/route";
import userModule from "@/utils/userInfo";
import { MessageBox, Notification } from "element-ui";

export default {
  name: "Route",
  components: { Editor, Toolbar },
  data() {
    return {
      defaultCover,
      page: 1,
      pageSize: 10,
      total: 0,
      currentPage: 1,
      routeList: [],
      loading: false,
      updateDialogVisible: false,
      updateLoading: false,
      uploadLoading: false,
      geographyList: [],
      rules: {
        name: [{ required: true, message: "请输入线路名称", trigger: "blur" }],
        temperature: [
          { required: true, message: "请输入温度", trigger: "blur" },
          { pattern: /^[-]{0,1}[0-9]+$/, message: "请输入数字" },
        ],
        geographyId: [
          { required: true, message: "请选择地理情况", trigger: "blur" },
        ],
        introduce: [{ required: true, message: "请输入介绍", trigger: "blur" }],
        cover: [{ required: true, message: "请上传图片", trigger: "blur" }],
        detail: [{ required: true, message: "请输入详情", trigger: "blur" }],
      },
      updateData: {},
      // 富文本框配置
      editor: null,
      html: "",
      toolbarConfig: {},
      editorConfig: {
        placeholder: "请输入内容...",
        MENU_CONF: {},
      },
      mode: "default", // or 'simple'
    };
  },
  created() {
    this.getUserRoute();
    this.getGeographyList();
    // 图片配置设置
    this.configImage();
    // 视频配置设置
    this.configVideo();
  },
  beforeDestroy() {
    const editor = this.editor;
    if (editor == null) return;
    editor.destroy(); // 组件销毁时，及时销毁编辑器
  },
  methods: {
    // 获取用户发布的线路
    async getUserRoute() {
      try {
        this.loading = true;
        const res = await getRouteList({
          page: this.page,
          pageSize: this.pageSize,
          userId: userModule.getUser().id,
        });
        this.routeList = res.data.records;
        this.total = res.data.total;
      } catch {
        this.$message.error("获取线路失败");
      } finally {
        this.loading = false;
      }
    },
    // 时间格式判断
    padZero(num) {
      return num < 10 ? "0" + num : num;
    },
    // 时间格式化
    formatDate(timeArray) {
      if (!timeArray) return "暂无时间";
      let year = timeArray[0];
      let month = this.padZero(timeArray[1]);
      let day = this.padZero(timeArray[2]);
      let hour = this.padZero(timeArray[3]);
      let minute = this.padZero(timeArray[4]);
      let second = this.padZero(timeArray[5]) || "00";
      return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
    },
    // 跳转到详情页
    async toDetail(item) {
      // 新增访问量
      item.views = item.views + 1;
      const res = await addRouteViews({ id: item.id, views: item.views });
      this.$router.push(`/routeDetail/${item.id}`);
    },
    // 获取所有地理信息
    async getGeographyList() {
      const res = await getGeographyList();
      this.geographyList = res.data;
    },
    // 编辑信息
    edit(row) {
      this.updateDialogVisible = true;
      this.updateData = { ...row };
      this.html = this.updateData.detail;
    },
    // 修改信息
    async update() {
      this.updateData.detail = this.html;
      this.$refs.updateForm.validate(async (v) => {
        if (v) {
          try {
            this.updateLoading = true;
            const res = await updateRoute(this.updateData);
            this.updateDialogVisible = false;
            this.getUserRoute();
          } finally {
            this.updateLoading = false;
          }
        }
      });
    },
    // 删除
    async del(row) {
      MessageBox.confirm("确定删除所选数据吗？", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then(async () => {
        const notify = Notification({
          title: "正在删除",
          message: "请稍后...",
          showClose: false,
          iconClass: "el-icon-loading",
          duration: 0,
        });
        try {
          const res = await deleteById([row.id]);
          await this.getUserRoute();
          notify.close();
          Notification.success({
            title: "删除成功",
            duration: 2000,
          });
        } catch {
          notify.close();
          Notification.error({
            title: "错误",
            message: "删除失败",
            duration: 2000,
          });
        }
      });
    },
    // 选择文件，上传封面
    async changeFile(file) {
      // 判断格式是否正确
      const bool = this.verifyFormat(file);
      if (!bool) {
        return;
      }
      // 上传到服务器
      // console.log("上传到服务器,返回图片路径赋值给insertForm.cover");
      this.uploadLoading = true;
      try {
        let formData = new FormData();
        // 拿到存在file中的文件存放到formData中
        formData.append("file", file.raw);
        const res = await uploadFile(formData);
        this.updateData.cover = res.data;
      } finally {
        this.uploadLoading = false;
      }
    },
    // 上传封面前校验格式
    verifyFormat(file) {
      const isJPG =
        file.raw.type === "image/jpeg" || file.raw.type === "image/png";
      const isLt10M = file.raw.size / 1024 / 1024 < 10;
      if (!isJPG) {
        this.$message.error("上传头像图片只能是 jpg/jpeg/png 格式!");
        return false;
      }
      if (!isLt10M) {
        this.$message.error("上传头像图片大小不能超过 10MB!");
        return false;
      }
      return isJPG && isLt10M;
    },
    // 分页
    handleCurrentChange(page) {
      this.page = page;
      this.currentPage = page;
      this.getUserRoute();
    },
    // 关闭修改弹窗
    handleCloseUpdate() {
      this.updateLoading = false;
      this.$refs.updateForm.resetFields();
    },
    // 富文本框配置
    onCreated(editor) {
      this.editor = Object.seal(editor); // 一定要用 Object.seal() ，否则会报错
    },
    // 富文本框自定义图片上传
    configImage() {
      this.editorConfig.MENU_CONF["uploadImage"] = {
        // 自动定义上传图片
        async customUpload(file, insertFn) {
          // 判断格式是否正确
          const isJPG = file.type === "image/jpeg" || file.type === "image/png";
          const isLt10M = file.size / 1024 / 1024 < 10;
          if (!isJPG) {
            this.$message.error("上传图片只能是 jpg/jpeg/png 格式!");
            return false;
          }
          if (!isLt10M) {
            this.$message.error("上传图片大小不能超过 10MB!");
            return false;
          }

          const notify = Notification({
            title: "提示",
            message: "正在上传图片",
            showClose: false,
            iconClass: "el-icon-loading",
            duration: 0,
          });
          try {
            // 上传到服务器
            let formData = new FormData();
            // 拿到存在file中的文件存放到formData中s
            formData.append("file", file);
            const res = await uploadFile(formData);
            insertFn(res.data);
            notify.close();
            Notification.success({
              title: "上传成功",
              duration: 2000,
            });
          } catch {
            notify.close();
            Notification.error({
              title: "错误",
              message: "上传失败",
              duration: 2000,
            });
          }
        },
      };
    },
    // 富文本框自定义视频上传
    configVideo() {
      this.editorConfig.MENU_CONF["uploadVideo"] = {
        // 自动定义上传视频
        async customUpload(file, insertFn) {
          // 判断格式是否正确
          const isJPG = file.type === "video/mp4";
          const isLt20M = file.size / 1024 / 1024 < 20;
          if (!isJPG) {
            this.$message.error("上传视频只能是 mp4 格式!");
            return false;
          }
          if (!isLt20M) {
            this.$message.error("上传视频大小不能超过 20MB!");
            return false;
          }

          const notify = Notification({
            title: "提示",
            message: "正在上传视频",
            showClose: false,
            iconClass: "el-icon-loading",
            duration: 0,
          });
          try {
            // 上传到服务器
            let formData = new FormData();
            // 拿到存在file中的文件存放到formData中s
            formData.append("file", file);
            const res = await uploadFile(formData);
            insertFn(res.data);
            notify.close();
            Notification.success({
              title: "上传成功",
              duration: 2000,
            });
          } catch {
            notify.close();
            Notification.error({
              title: "错误",
              message: "上传失败",
              duration: 2000,
            });
          }
        },
      };
    },
  },
};
</script>

<style lang="less" scoped>
.route {
  height: 100%;
  padding-top: 2px;
  box-shadow: 0 0 6px #ccc;
  .item {
    display: flex;
    margin: 20px;
    padding-bottom: 6px;
    height: 50px;
    border-bottom: 1px solid #ddd;
    .left {
      width: 50%;
      .title {
        margin-left: 10px;
        margin-top: 10px;
        padding-bottom: 2px;
        width: fit-content;
        max-width: 100%;
        text-align: left;
        font-size: 15px;
        font-weight: 600;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        cursor: pointer;
        &:hover {
          border-bottom: 2px solid #aaa;
        }
      }
    }
    .right {
      width: 50%;
      display: flex;
      .show {
        width: 88%;
        display: flex;
        flex-direction: column;
        align-items: flex-end;
        justify-content: space-between;
        color: #999;
        font-size: 14px;
        span {
          margin-left: 10px;
          i {
            margin-right: 4px;
          }
        }
      }
      .option {
        cursor: pointer;
        flex: 1;
        line-height: 2;
      }
    }
  }
  .tip {
    position: absolute;
    margin-left: 10px;
    width: 100%;
    font-size: 12px;
    color: #aaa;
  }
  .upload-cover {
    position: relative;
    display: flex;
    width: 140px;
    height: 140px;
    .cover {
      width: 100%;
      height: 100%;
      position: relative;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      img {
        width: 100%;
        height: 100%;
        cursor: pointer;
      }
      span {
        position: absolute;
        top: 50%;
        left: 50%;
        width: 134px;
        height: 134px;
        transform: translate(-50%, -50%);
        &::before {
          content: "上传封面";
          position: absolute;
          top: 50%;
          left: 50%;
          transform: translate(-50%, -50%);
          width: 134px;
          height: 134px;
          background-color: rgba(0, 0, 0, 0.06);
          text-align: center;
          line-height: 134px;
          cursor: pointer;
          opacity: 0;
          visibility: hidden;
          z-index: 1;
          color: black;
        }
        &:hover::before {
          opacity: 1;
          visibility: visible;
        }
      }
    }
  }
  .editor-container {
    text-align: left;
    border: 1px solid;
  }
}
</style>